package tau.dimes.visualization.applet.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Represents a trace data set, a list of nodes and traces.
 */
public class TraceDataSet
{
	private Map<String, Hop> hops;
	private List<Trace> traces;
	private float minLongitude = -180;
	private float maxLongitude = 180;
	private float minLatitude = -90;
	private float maxLatitude = 90;
	private boolean isComputed = false;
	private int maxEdges;

	/**
	 * Constructs a new TraceDataSet.
	 */
	public TraceDataSet()
	{
		hops = new HashMap<String, Hop>();
		traces = new ArrayList<Trace>();
	}

	/**
	 * Adds a new hop to the hops map.
	 * @param hop The Hop instance to add.
	 */
	public void addHop(Hop hop)
	{
		this.hops.put(hop.getId(), hop);
		float longitude = hop.getLongitude();
		float latitude = hop.getLatitude();
		
		if (isComputed)
		{
			setMinLongitude(Math.min(getMinLongitude(), longitude));
			setMaxLongitude(Math.max(getMaxLongitude(), longitude));
			setMinLatitude(Math.min(getMinLatitude(), latitude));
			setMaxLatitude(Math.max(getMaxLatitude(), latitude));
		}
		else
		{
			setMinLongitude(longitude);
			setMaxLongitude(longitude);
			setMinLatitude(latitude);
			setMaxLatitude(latitude);
			isComputed = true;
		}
	}
	
	/**
	 * Adds a new trace to the trace list.
	 * @param trace A Trace instance to add.
	 */
	public void addTrace(Trace trace)
	{
		this.traces.add(trace);
		
		setMaxEdges(Math.max(getMaxEdges(), trace.size()));
	}

	private void setMinLongitude(float minLongAngle)
	{
		this.minLongitude = minLongAngle;
	}

	/**
	 * Gets the minimal longitude of this set.
	 * @return - Minimal longitude of this set.
	 */
	public float getMinLongitude()
	{
		return minLongitude;
	}

	private void setMaxLongitude(float maxLongAngle)
	{
		this.maxLongitude = maxLongAngle;
	}

	/**
	 * Gets the maximal longitude of this set.
	 * @return - Maximal longitude of this set.
	 */
	public float getMaxLongitude()
	{
		return maxLongitude;
	}

	private void setMinLatitude(float minLatAngle)
	{
		this.minLatitude = minLatAngle;
	}

	/**
	 * Gets the minimal latitude of this set.
	 * @return - Minimal latitude of this set.
	 */
	public float getMinLatitude()
	{
		return minLatitude;
	}

	private void setMaxLatitude(float maxLatAngle)
	{
		this.maxLatitude = maxLatAngle;
	}

	/**
	 * Gets the maximal latitude of this set.
	 * @return - Maximal latitude of this set.
	 */
	public float getMaxLatitude()
	{
		return maxLatitude;
	}
	
	/**
	 * Gets a map of all hops in the set.
	 * @return - A map of all hops in the set. 
	 */
	public Map<String, Hop> getHops()
	{
		return hops;
	}

	/**
	 * Gets a list of all traces in the set.
	 * @return A list of all traces in the set.
	 */
	public List<Trace> getTraces()
	{
		return traces;
	}

	private void setMaxEdges(int maxEdges)
	{
		this.maxEdges = maxEdges;
	}

	/**
	 * Gets the edge count of the longest trace in the set.
	 * @return The edge count of the longest trace in the set.
	 */
	public int getMaxEdges()
	{
		return maxEdges;
	}
}